import java.io.*;
import java.net.*;

public class StopAndWaitServer {
    private static final int SERVER_PORT = 9876;

    public static void main(String[] args) {
        DatagramSocket serverSocket = null;
        try {
            serverSocket = new DatagramSocket(SERVER_PORT);
            System.out.println("Server is running...");

            // Establish connection
            DatagramPacket connectPacket = receivePacket(serverSocket);
            InetAddress clientAddress = connectPacket.getAddress();
            int clientPort = connectPacket.getPort();

            // Receive file
            FileOutputStream fileOutputStream = new FileOutputStream("D:/456.txt");
            boolean endOfFile = false;

            while (!endOfFile) {
                DatagramPacket dataPacket = receivePacket(serverSocket);
                byte[] data = dataPacket.getData();
                int sequenceNumber = data[0];

                // Simulate error detection
                if (Math.random() > 0.1) {
                    sendAck(serverSocket, clientAddress, clientPort, sequenceNumber);

                    // Write data to file
                    fileOutputStream.write(data, 1, dataPacket.getLength() - 1);

                    // Check if it's the last packet
                    endOfFile = dataPacket.getLength() < 1024;
                } else {
                    System.out.println("Packet with sequence number " + sequenceNumber + " dropped.");
                }
            }

            System.out.println("File received successfully.");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (serverSocket != null && !serverSocket.isClosed()) {
                serverSocket.close();
            }
        }
    }

    private static DatagramPacket receivePacket(DatagramSocket socket) throws IOException {
        byte[] receiveData = new byte[1024];
        DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
        socket.receive(receivePacket);
        return receivePacket;
    }

    private static void sendAck(DatagramSocket socket, InetAddress clientAddress, int clientPort, int sequenceNumber) throws IOException {
        byte[] ackData = { (byte) sequenceNumber };
        DatagramPacket ackPacket = new DatagramPacket(ackData, ackData.length, clientAddress, clientPort);
        socket.send(ackPacket);
    }
}

